package cn.huaqingcheng.tianshu.common.core.model;

import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.jetbrains.annotations.Nullable;

import java.io.Serial;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 简单属性映射
 * <p>
 * 对 map 的扩展 以允许当值为 {@code Object} 时类型安全(伪)的读取, <br>
 * 比 {@code JSONObject} 更通用些, 且不和具体的 json 实现关联
 */
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@ToString(doNotUseGetters = true)
public final class AttributeMap<V> extends HashMap<String, V> implements JsonStructure {

    @Serial
    private static final long serialVersionUID = 1L;

    public AttributeMap(int initialCapacity) {
        super(initialCapacity);
    }

    public static <V> AttributeMap<V> of(@Nullable Map<String, V> map) {
        AttributeMap<V> attributeMap = new AttributeMap<>();
        if (map != null) {
            attributeMap.putAll(map);
        }
        return attributeMap;
    }

    public static <V> AttributeMap<V> of() {
        return new AttributeMap<>(0);
    }

    public Optional<V> getOpt(String key) {
        return Optional.ofNullable(get(key));
    }

    public Optional<Long> getLongOpt(String key) {
        return Optional.ofNullable(getLong(key));
    }

    @Nullable
    public Long getLong(String key) {
        V v = get(key);
        if (v == null) {
            return null;
        }

        if (v instanceof Long l) {
            return l;
        }

        return Long.valueOf(String.valueOf(v));
    }

    public Optional<String> getStringOpt(String key) {
        return Optional.ofNullable(getString(key));
    }

    @Nullable
    public String getString(String key) {
        V v = get(key);
        if (v == null) {
            return null;
        }

        if (v instanceof String s) {
            return s;
        }

        return String.valueOf(v);
    }

    public String getStringOrEmpty(String key) {
        String str = getString(key);
        return str != null ? str : "";
    }

}
